package cn.com.open.itembank.dto;

import cn.com.open.itembank.common.Function;
import cn.com.open.itembank.interceptor.Log;
import cn.com.open.itembank.utils.StringUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;

/**
 * Created by lucky on 2017/7/20.
 */

/**
 * 日志描述DTO
 */
public class OperateDescription {
    private String controllerName = "";
    private String actionName = "";
    private String actionParam = "";
    private String httpHeader = "";
    private String customIp = "";
    private String method = "";
    private String description = "";
    private String optUrl = "";
    private String optType = "";

    /**
     * Gets action param.
     *
     * @return the action param
     */
    public String getActionParam() {
        return actionParam;
    }

    /**
     * Gets description.
     *
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * Sets description.
     *
     * @param description the description
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Gets controller name.
     *
     * @return the controller name
     */
    public String getControllerName() {
        return controllerName;
    }

    /**
     * Gets action name.
     *
     * @return the action name
     */
    public String getActionName() {
        return actionName;
    }

    /**
     * Sets action name.
     *
     * @param actionName the action name
     */
    public void setActionName(String actionName) {
        this.actionName = actionName;
    }

    /**
     * Gets http header.
     *
     * @return the http header
     */
    public String getHttpHeader() {
        return httpHeader;
    }

    /**
     * Gets custom ip.
     *
     * @return the custom ip
     */
    public String getCustomIp() {
        return customIp;
    }

    /**
     * Sets custom ip.
     *
     * @param customIp the custom ip
     */
    public void setCustomIp(String customIp) {
        this.customIp = customIp;
    }

    /**
     * Gets method.
     *
     * @return the method
     */
    public String getMethod() {
        return method;
    }

    /**
     * Sets method.
     *
     * @param method the method
     */
    public void setMethod(String method) {
        this.method = method;
    }

    /**
     * Gets opt url.
     *
     * @return the opt url
     */
    public String getOptUrl() {
        return optUrl;
    }

    /**
     * Sets opt url.
     *
     * @param optUrl the opt url
     */
    public void setOptUrl(String optUrl) {
        this.optUrl = optUrl;
    }

    /**
     * Gets opt type.
     *
     * @return the opt type
     */
    public String getOptType() {
        return optType;
    }

    /**
     * Sets opt type.
     *
     * @param optType the opt type
     */
    public void setOptType(String optType) {
        this.optType = optType;
    }

    /**
     * Sets action param.
     *
     * @param actionParam the action param
     */
    public void setActionParam(String actionParam) {

        this.actionParam = actionParam;
    }

    /**
     * 截取ControllerName
     *
     * @param controllerName the controller name
     */
    public void setControllerName(String controllerName) {
        this.controllerName = controllerName.substring(".".lastIndexOf(controllerName) + 1);
    }

    /**
     * 设置http头信息.
     *
     * @param httpHeader the http header
     */
    public void setHttpHeader(String httpHeader) {
        this.httpHeader = httpHeader;
    }

    /**
     * 创建操作日志描述对象.
     *
     * @param controllerName the controller name
     * @param actionName     the action name
     * @param args           the args
     * @param log            the log
     * @param request        the request
     * @return the description info
     */
    public static OperateDescription getDescriptionInfo(String controllerName, String actionName, Object[] args,
                                                        Log log, HttpServletRequest request) {
        OperateDescription operateDescription = new OperateDescription();
        operateDescription.setControllerName(controllerName);
        operateDescription.setActionName(actionName);
        operateDescription.setHttpHeader(getHttpHeader(request));
        operateDescription.setCustomIp(Function.getIp(request));
        operateDescription.setMethod(request.getMethod());
        operateDescription.setOptUrl(request.getRequestURI() == null ? "" : request.getRequestURI());
        operateDescription.setOptType(log.optType());
        operateDescription.setActionParam(getActionParam(request, args));
        operateDescription.setDescription(getDescription(request, log.keyName(), log.optDescription()));

        return operateDescription;
    }

    //region 私有方法
    /**
     * 获得http头.
     *
     * @param request the request
     * @return the http header
     */
    private static String getHttpHeader(HttpServletRequest request) {
        Enumeration<String> headerNames = request.getHeaderNames();
        StringBuilder sbHeader = new StringBuilder();
        //将头信息转换指定格式返回
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            String value = request.getHeader(key);
            sbHeader.append(key + ":" + value + " ");
        }
        return sbHeader.toString();
    }

    /**
     * 请求参数拼装
     *
     * @param paramsArray
     * @return
     */
    private static String argsArrayToString(Object[] paramsArray) {
        String params = "";
        StringBuilder sbParams = new StringBuilder();
        if (paramsArray != null && paramsArray.length > 0) {
            for (Integer i = 0; i < paramsArray.length; i++) {
                boolean isObject = true;
                if (paramsArray[i] instanceof HttpServletRequest || paramsArray[i] instanceof HttpServletResponse) {
                    isObject = false;
                }
                if (isObject) {
                    Object jsonObj = JSON.toJSON(paramsArray[i]);
                    sbParams.append(jsonObj.toString() + " ");
                }
            }
        }
        params = sbParams.toString();
        return params.trim();
    }


    /**
     * 得到方法参数列表.
     *
     * @param request     the request
     * @param paramsArray the params array
     * @return the action param
     */
    private static String getActionParam(HttpServletRequest request, Object[] paramsArray) {
        String requestMethod = request.getMethod();
        String params = "";
        String post = "POST";

        if (post.equals(requestMethod)) {
            params = argsArrayToString(paramsArray);
        } else {
            Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            params = paramsMap.toString();
        }

        return params;
    }

    /**
     * 得到描述文字.
     *
     * @param request     the request
     * @param keyName     the key name
     * @param description the description
     * @return the description
     */
    private static String getDescription(HttpServletRequest request, String keyName, String description) {
        String requestMethod = request.getMethod();
        String returnDescription = "";
        String post = "POST";

        if (!post.equals(requestMethod)) {
            Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);

            if (!StringUtil.isEmpty(keyName)) {
                for (Map.Entry<?, ?> param : paramsMap.entrySet()) {
                    if (param.getKey().toString().equalsIgnoreCase(keyName)) {
                        returnDescription = String.format(description, param.getValue());
                    }
                }
            }
        }

        return returnDescription;
    }
    //endregion
}
